%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "y.tab.h"
#include "ts2006.h"

static int cima=0;
int yyerror(char *);
extern int yylex(void);
extern int yylineno;
extern char *yytext;
FILE* salida;
int tabla_simbolos[200];
void compara_cad(char *, char *);
void existe_id(int, char *);
void no_existe_id(int , char *);
void compara_2cad(char *, char* , char *);
void compara_3cad(char *, char* , char *, char *);
void inserta(int, char *);
extern int inserta_ts(int, char *);
char *lexema;
%}

%union  {
  char cadena[128];
  int numero;
}

%token IDENTIF_ERROR_GUIONES IDENTIF_ERROR_GENERAL C_ENTERA_ERROR_2_GUIONES C_ENTERA_ERROR_GENERAL T_ENTERO_ERROR COMENTARIO STRING_ERROR STRING_SIN_CERRAR SALTO_LINEA OP_ASIGNACION OP_TIPO OP_DELIMITADOR OP_ARIT_SUMAR PUNTO ABRE_PARENTESIS CIERRA_PARENTESIS COMA OP_RELACIONAL ERROR ENTERO_ERROR_GRANDE
	
%token <cadena> PALABRA_RESERVADA IDENTIF STRING
%token <numero> C_ENTERA T_ENTERO



%start paquete
%%

paquete               : declaracion_paquete
                      ;
                      
declaracion_paquete   : PALABRA_RESERVADA IDENTIF
	                    PALABRA_RESERVADA declaraciones
	                    PALABRA_RESERVADA IDENTIF OP_DELIMITADOR
                            {
                                compara_cad($1,"package");
                                compara_cad($3,"is");
                                compara_cad($5,"end");
                             }        
                      ;
                             
declaracion_subprograma : PALABRA_RESERVADA IDENTIF OP_DELIMITADOR
                            { compara_cad($1, "procedure"); }
                      ;

                        
                     
declaraciones         : declaraciones declaracion_subprograma
                      | /* lambda */   // <- asi?
                      ; 
                     

%%

void compara_cad(char *cad1, char *cad2) {
  if (strcmp(cad1, cad2)) yyerror("sintax error");
}

void compara_2cad(char *cad1, char* cad2, char *cad3) {
  if (strcmp(cad1, cad2) || strcmp(cad1, cad3)) yyerror("sintax error");
}


void compara_3cad(char *cad1, char* cad2, char *cad3, char *cad4) {
  if (strcmp(cad1, cad2) || strcmp(cad1, cad3) || strcmp(cad1, cad4)) yyerror("sintax error");
}

void inserta(int id, char *cad) {
    if(inserta_ts(id, cad)==-1)
         yyerror("Identicador existente");
}

void existe_id(int id, char *cad) {
  if(existe_entrada(id, cad)==0) 
	yyerror("Identificador ya declarado");
}

void no_existe_id(int id,char *cad) {
  if(existe_entrada(id, cad)==1) 
		  yyerror("Identificador no declarado previamente");
}

int yyerror(char *s) {
  printf("%s en la linea %d. Token \"%s\"\n",s, yylineno, yytext);
  return 0;
	
}





int main(int argc, char *argv[]){
  

  //  FILE* tokens             = NULL;  //  Haria falta
  //  FILE* tablas             = NULL;  //  Haria falta

  extern FILE *yyin;
  int i;

  //  t_fase  fase_actual      = DECLARACION_FUNCIONES;  //  Dira donde estamos
  

  if(argc == 4) 
  {  //  Posiblemente necesitaremos 4
	  yyin = fopen(argv[1],"r");
	  if(!yyin) 
	  {
		perror("Error abriendo el fichero de entrada\n");
		exit(-1);
	  }
	  if((salida = fopen(argv[2], "w")) == NULL)
	  {
		perror("Error abriendo el fichero de entrada\n");
		exit(-1);
	  }    
  } 
  else 
  {
	fprintf(stderr,"Uso %s <fichero_entrada> <fichero_salida> <fichero_tabla>\n", argv[0]);
	exit(-1);
  }
  
  //Inicializacion array de identificadores de tablas de simbolos
  memset(tabla_simbolos,-1,sizeof(tabla_simbolos));
  
  yyparse();
  
  //escribir_tabla(tabla_simbolos, argv[3]);

  escribir_tabla(tabla_simbolos[cima], argv[3]);
    
  fclose(salida);
  for (i=0;i<100;i++)  //  Forma muy cutre de destruir las tablas
	if (existe_tabla(i))
	 destruir_tabla(i);
  return 0;
}
